#include "stdafx.h"
#include "Road3dParamGen.h"
#include "RoadMileLine.h"
#include "RoadDesign.h"
void General3dParamGen::GenNormal(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vNormal) const
{

	vNormal.resize(vPnt.size(), ZMPoint3D(0, 0, 0));
#pragma loop(hint_parallel(8))  
	for (int i = 0; i < vInx.size(); i += 3)
	{
		int inx[3] = { vInx[i], vInx[i + 1],vInx[i + 2] };
		ZMPoint3D pnt[3] = { vPnt[vInx[i]], vPnt[vInx[i + 1]], vPnt[vInx[i + 2]] };
		ZMPoint3D dir1 = (pnt[1] - pnt[0]), dir2 = pnt[2] - pnt[0];
		for (int j = 0; j < 3; ++j)
		{
			ZMPoint3D dir = dir1.Crossed(dir2);
			if (dir[2] < 0) dir *= (-1);
			vNormal[inx[j]] = vNormal[inx[j]] + dir;
			//	vNormalNum[inx[j]]++;
		}
	}

#pragma loop(hint_parallel(8))  
	for (int i = 0; i < vNormal.size(); i++)
	{
		vNormal[i].Normalize();
		if (vNormal[i][2] < 0) vNormal[i] *= -1;
	}
}

void General3dParamGen::GenTangent(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vTangent) const
{
	vTangent.resize(vPnt.size(), ZMPoint3D(1, 0, 0));
}

Road3dParamGen::Road3dParamGen(SharedPointer<RoadMileLine>& pRoadMile, const ZMReal& uPlusDivMile, const ZMReal& vPlusDivDis)
{
	m_pRoadMile = pRoadMile;
	m_uPlusDivMile = uPlusDivMile;
	m_vPlusDivDis = vPlusDivDis;
}

Road3dParamGen::Road3dParamGen(RoadDesign& road, const ZMReal& uPlusDivMile, const ZMReal& vPlusDivDis)
{
	m_pRoadMile = road.GetCrossData()->GetMileData();
	m_uPlusDivMile = uPlusDivMile;
	m_vPlusDivDis = vPlusDivDis;
}

ZMVector<ZMPoint2D> Road3dParamGen::GenUV(const ZMVector<ZMPoint3D>& vPnt) const
{
	ZMVector<ZMPoint2D> ret;
	ret.resize(vPnt.size());
	for (int i=0; i<vPnt.size(); ++i)
	{
		ZMPoint3D pnt = vPnt[i], pntOnMile;
		ZMReal fAngle;
		ZMReal fMileValue = m_pRoadMile->GetMileValue(pnt, pntOnMile, fAngle);
		ZMReal dis = pnt.Distance(pntOnMile, ZMPoint3D::TYPE_2D);
		double dx = fMileValue / m_uPlusDivMile;
		double dy = dis / m_vPlusDivDis;
		dx = ((int)dx) % 2 + (dx - (int)dx);	dx = dx < 1 ? dx : 2 - dx;
		dy = ((int)dy) % 2 + (dy - (int)dy);	dy = dy < 1 ? dy : 2 - dy;
		ret[i] = ZMPoint2D(dx, dy);
	}
	return ret;
}

Road3dParamGen::~Road3dParamGen()
{
}

void  Road3dParamGen::GenTangent(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vTangent) const
{
	vTangent.resize(vPnt.size(), ZMPoint3D(1, 0, 0));
#pragma loop(hint_parallel(8))  
	for (int i = 0; i < vPnt.size(); i++)
	{
		vTangent[i] = m_pRoadMile->GetMileDir(vPnt[i]);
		vTangent[i].Normalize();

	}
}

Plane3dParamGen::Plane3dParamGen(const ZMReal& uPlusDivDis, const ZMReal& vPlusDivDis)
{
	m_uPlusDivDis = uPlusDivDis;
	m_vPlusDivDis = vPlusDivDis;
}

ZMVector<ZMPoint2D> Plane3dParamGen::GenUV(const ZMVector<ZMPoint3D>& vPnt) const
{
	ZMVector<ZMPoint2D> ret;
	ret.resize(vPnt.size());

	ZMReal xMin = vPnt[0].x(), yMin = vPnt[0].y();
	for (int i = 0; i < vPnt.size(); ++i)
	{
		xMin = vPnt[i].x() > xMin ? xMin : vPnt[i].x();
		yMin = vPnt[i].y() > yMin ? yMin : vPnt[i].y();
	}
	for (int i = 0; i < vPnt.size(); ++i)
	{
		ZMPoint3D pnt = vPnt[i], pntOnMile;
		ZMReal fAngle;
		ZMReal xValue = pnt.x() - xMin;
		ZMReal yValue = pnt.y() - yMin;
		double dx = xValue / m_uPlusDivDis;
		double dy = yValue / m_vPlusDivDis;
		dx = ((int)dx) % 2 + (dx - (int)dx);	dx = dx < 1 ? dx : 2 - dx;
		dy = ((int)dy) % 2 + (dy - (int)dy);	dy = dy < 1 ? dy : 2 - dy;
		ret[i] = ZMPoint2D(dx, dy);
	}
	return ret;
}

